module;
#include <cstdint> //https://zh.cppreference.com/w/cpp/types/integer
#include <array>
#include <span>
#include <cassert>

export module cpu6502:hardware;

export namespace nes8
{
    using byte6502 = uint8_t;
    using ptr_6502 = uint16_t;
    using cycle_type = uint64_t;

    struct cpu_register
    {
        byte6502 a = 0;     //累加寄存器
        byte6502 x = 0;
        byte6502 y = 0;
        byte6502 sp = 0;    //栈指针
        ptr_6502 pc = 0;    //程序计数器
        byte6502 p = 0;     //标志寄存器
    };

    struct memory
    {
        using byte_array = std::array<byte6502, 0x10000>;
        byte_array data;
        // byte_array::size_type offset_last;

        constexpr const byte6502 &operator[](ptr_6502 address) const { return data[address]; }
        constexpr byte6502 &operator[](ptr_6502 address) { return data[address]; }

        // 访问一块内存
        // HACK 返回的span,如果越界访问未定义行为
        constexpr std::span<byte6502> operator[](ptr_6502 offset, std::size_t size)
        {
            assert(size + offset <= std::tuple_size<byte_array>{});

            return {data.begin() + offset, size};
        }
    };

    struct CPU6502
    {
        cpu_register reg;

        CPU6502();
        //BUG 注意,constexpr函数不能放到其他模块定义
        // constexpr void load_byte6502(memory &);
        void load_byte6502(memory &);
        void load_addr6502(memory &);
        void register_reset();
        void execute_one_instruction();
    };
} // namespace nes8
